package com.example.tys.baseapplication.util;

import android.support.annotation.IntRange;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Created by tys on 2019/5/7.
 */

public class LogUtils {

    private static final String TAG = "LogUtils";

    /**
     * log分页大小(实际比4000小一点)
     */
    private static int LOG_MAX_LENGTH = 3 * 1024;

    /**
     * 当前日志打印等级
     */
    private static int CURRENT_LOG_LEVEL;

    /**
     * 是否将日志写入文件
     */
    private static boolean LOG_IN_FILE = true;

    /**
     * 记录日志文件目录
     */
    private static String LOG_FILE_DIR;

    public static void v(String tag, String msg) {
        printfSub(tag, msg, Log.VERBOSE);
    }

    public static void d(String tag, String msg) {
        printfSub(tag, msg, Log.DEBUG);
    }

    public static void i(String tag, String msg) {
        printfSub(tag, msg, Log.INFO);
    }

    public static void w(String tag, String msg) {
        printfSub(tag, msg, Log.WARN);
    }

    public static void e(String tag, String msg) {
        printfSub(tag, msg, Log.ERROR);
    }

    public static void e(String tag, Throwable e) {
        printfSub(tag, e.toString(), Log.ERROR);
    }


    public static int getLogLevel() {
        return CURRENT_LOG_LEVEL;
    }


    /**
     * @param logLevel 日志打印等级
     * @param logInFile 是否写入本地文件
     * @param fileDir 写入本地文件的目录
     */
    public static void init(@IntRange(from = Log.VERBOSE, to = Log.ERROR) int logLevel, boolean logInFile, String fileDir) {
        LOG_FILE_DIR = fileDir;
        LOG_IN_FILE = logInFile;
        CURRENT_LOG_LEVEL = logLevel;
        deleteOverdueFiles();
    }

    private static void deleteOverdueFiles() {
        if (!TextUtils.isEmpty(LOG_FILE_DIR)) {
            try {
                File file = FileUtils.getFile(LOG_FILE_DIR);
                //1天
                long dif = System.currentTimeMillis() - 1 * 8640000;
                File[] files = file.listFiles();
                for (File f : files) {
                    if (f.isFile() && FileUtils.isFileOlder(f, dif)) {
                        Log.d(TAG, "删除日志文件 " + f.getName() + " " + f.lastModified());
                        FileUtils.forceDelete(f);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 分段日志打印 过长打印不全
     *
     * @param tag
     * @param msg
     * @param level
     */
    private static void printfSub(String tag, String msg, int level) {
        byte[] bytes = msg.getBytes();
        int total = bytes.length;
        if (msg.length() < LOG_MAX_LENGTH) {
            printf(tag, msg, level);
            return;
        }
        for (int current = 0, left = total; left > 0; current += LOG_MAX_LENGTH, left = total - current) {
            if (left > LOG_MAX_LENGTH) {
                printf(tag + "(" + current + "-" + (current + LOG_MAX_LENGTH) + ")",
                        new String(bytes, current, LOG_MAX_LENGTH), level);
            } else {
                printf(tag + "(" + current + "-" + total + ")", new String(bytes, current, left), level);
            }
        }
    }

    private static void printf(String tag, String msg, int level) {
        if (level < CURRENT_LOG_LEVEL) {
            return;
        }
        switch (level) {
            case Log.DEBUG:
                Log.d(tag, msg);
                write2file(trans2WriteFileData(tag, msg, "d"));
                break;
            case Log.INFO:
                Log.i(tag, msg);
                write2file(trans2WriteFileData(tag, msg, "i"));
                break;
            case Log.WARN:
                Log.w(tag, msg);
                write2file(trans2WriteFileData(tag, msg, "w"));
                break;
            case Log.ERROR:
                Log.e(tag, msg);
                write2file(trans2WriteFileData(tag, msg, "e"));
                break;
            default:
                //ignore
        }
    }

    /**
     * 转换成要写入日志文件的字符串
     *
     * @param tag
     * @param msg
     * @param flag i d w e
     * @return
     */
    private static String trans2WriteFileData(String tag, String msg, String flag) {
        //时间 e/tag: xxx
        return getData("MM-dd hh:mm:ss") + " " + flag + "/" + tag + ": " + msg + "\r\n";
    }

    private static void write2file(String msg) {
        if (!LOG_IN_FILE) {
            return;
        }
        if (TextUtils.isEmpty(LOG_FILE_DIR)) {
            throw new RuntimeException("Set up the log file directory");
        }
        try {
            String fileName = getData("yyyy.MM.dd") + ".log";
            File file = FileUtils.getFile(LOG_FILE_DIR, fileName);
            FileUtils.writeStringToFile(file, msg, "UTF-8", true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String getData(String f) {
        SimpleDateFormat format = new SimpleDateFormat(TextUtils.isEmpty(f) ? "yyyy.MM.dd HH:mm:ss" : f, Locale.US);
        return format.format(new Date());
    }

}
